﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace ZOIL.Library.Behaviors
{
    [Obsolete("Legacy selection behavior", false)]
    public class ZLandscapeBoundingBoxSelectionBehavior : ZLandscapeSelectionBehavior
    {
        #region Private Properties

        private SelectionBoundingBoxAdorner _adorner; // Adorner drawing a Rectangle
        private ControlTemplate _boundingBoxTemplate;
        private AdornerLayer _rootWindowAdornerLayer; // Rootwindow

        #endregion

        #region Construct

        public ZLandscapeBoundingBoxSelectionBehavior(ContentControl targetControl)
            : base(targetControl)
        {
            SelectionStarted += OnSelectionStarted;
            SelectionChanged += OnSelectionChanged;
            SelectionFinished += OnSelectionFinished;
            SelectionCancelled += OnSelectionCancelled;
        }

        #endregion

        #region Events

        public void OnSelectionStarted(object sender, ZLandscapeSelectionEventArgs e)
        {
            var rootWindow = (Window) base.FindVisualTreeRoot(base.TargetControl); // Find Rootwindow to
            _rootWindowAdornerLayer = AdornerLayer.GetAdornerLayer((Visual) rootWindow.Content); // draw selection geometry

            if (_boundingBoxTemplate != null)
            {
                _adorner = new SelectionBoundingBoxAdorner((UIElement) rootWindow.Content, e.SelectionPoint, _boundingBoxTemplate);
                    // on its adorner layer
            }
            else
            {
                _adorner = new SelectionBoundingBoxAdorner((UIElement) rootWindow.Content, e.SelectionPoint); // on its adorner layer
            }

            _rootWindowAdornerLayer.Add(_adorner);
        }

        public void OnSelectionChanged(object sender, ZLandscapeSelectionEventArgs e)
        {
            _adorner.UpdateSelectionGeometry(e.SelectionPoint); // Updates selection geometry
        }

        public void OnSelectionFinished(object sender, ZLandscapeSelectionFinishedEventArgs e)
        {
            e.SelectedElements = GetElementsInGeometry(new RectangleGeometry(_adorner.SelectionGeometry), base.TargetControl, typeof (Image));
                // Get elements from Hittest
            e.SelectionGeometry = new RectangleGeometry(_adorner.SelectionGeometry); // Add Selection Geometry to event
            _rootWindowAdornerLayer.Remove(_adorner); // Remove selection geometry from windows adorner layer
        }

        public void OnSelectionCancelled(object sender, ZLandscapeSelectionFinishedEventArgs e)
        {
            _rootWindowAdornerLayer.Remove(_adorner); // Remove selection geometry from windows adorner layer
        }

        #endregion

        #region Set ControlTemplate for BoundingBox

        /// <summary>
        ///     Applies a custom template to the BoundingBox
        /// </summary>
        /// <param name="template"></param>
        public void SetBoundingBoxTemplate(ControlTemplate template)
        {
            _boundingBoxTemplate = template;
        }

        #endregion
    }

    #region BoundingBoxControl

    public class AdornerBoundingBox : UserControl
    {
        //BoundingBox has default template
        public AdornerBoundingBox()
        {
            var templateBorder = new Border();
            templateBorder.Background = new SolidColorBrush(Color.FromArgb(100, 0, 100, 0));
            templateBorder.CornerRadius = new CornerRadius(2);
            templateBorder.BorderBrush = Brushes.Black;
            templateBorder.BorderThickness = new Thickness(1.0);
            templateBorder.IsHitTestVisible = false;
            Content = templateBorder;
        }
    }

    #endregion

    #region Adorner Class

    public class SelectionBoundingBoxAdorner : Adorner
    {
        #region Private Properties

        private readonly Point _startPoint;
        private readonly VisualCollection visuals;

        #endregion

        #region Public Properties

        public Rect SelectionGeometry;
        public AdornerBoundingBox SelectionRectangle;

        #endregion

        #region Construct

        public SelectionBoundingBoxAdorner(UIElement designerItem, Point startPoint)
            : base(designerItem)
        {
            _startPoint = startPoint;
            SelectionGeometry = new Rect(_startPoint, _startPoint);
            SelectionRectangle = new AdornerBoundingBox();
            SnapsToDevicePixels = true;
            visuals = new VisualCollection(this);
            visuals.Add(SelectionRectangle);
        }

        public SelectionBoundingBoxAdorner(UIElement designerItem, Point startPoint, ControlTemplate template)
            : base(designerItem)
        {
            _startPoint = startPoint;
            SelectionGeometry = new Rect(_startPoint, _startPoint);
            SelectionRectangle = new AdornerBoundingBox();
            SelectionRectangle.Template = template;
            SnapsToDevicePixels = true;
            visuals = new VisualCollection(this);
            visuals.Add(SelectionRectangle);
        }

        #endregion

        #region Update Geometry

        public void UpdateSelectionGeometry(Point p)
        {
            SelectionGeometry = new Rect(_startPoint, p);
            InvalidateVisual(); // Forces Adorner to render again
        }

        #endregion

        #region Overriden Methods

        protected override int VisualChildrenCount
        {
            get { return visuals.Count; }
        }

        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            SelectionRectangle.Arrange(SelectionGeometry);
            return arrangeBounds;
        }

        protected override Visual GetVisualChild(int index)
        {
            return visuals[index];
        }

        #endregion
    }

    #endregion
}